package com.sunronsoft.mind.map;

import com.alibaba.fastjson.JSONArray;
import com.jfinal.kit.Kv;
import com.jfinal.kit.LogKit;
import com.jfinal.kit.PathKit;
import com.sunronsoft.mind.map.model.MindMap;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author Sunron
 **/
public class MindService {
    
    private static MindService service;
    private MindService() {}
    
    public static MindService getInstance() {
        if (null == service) service = new MindService();
        return service;
    }

    public String dataFile() {
        String path = PathKit.getWebRootPath() + "/data/";
        DataKit.processDirectory(path);

        return path + MainConfig.prop.get("mindData");
    }
    
    public boolean save(MindMap mindMap) {
        List<MindMap> mapList = this.list();
        if (mapList.isEmpty()) {
            mindMap.setType(0);
            mindMap.setId(1);
            mindMap.setDirection(MindMap.CENTER);
            mindMap.setExpanded(true);
            mindMap.setParentId(0);
        } else if (mindMap.getId() == null || mindMap.getId().equals(0)) {
            MindMap maxMap = Collections.max(mapList, Comparator.comparingInt(MindMap::getId));
            mindMap.setId(maxMap.getId() + 1);
        } else {
            mapList.removeIf(item -> mindMap.getId().equals(item.getId()));
        }
        mapList.add(mindMap);
        
        String fileName = this.dataFile();
        boolean success = DataKit.writeJsonFile(fileName, mapList.toString());
        LogKit.info(String.format("保存思维导图数据：%s", mindMap.toString()));
        return success;
    }

    public boolean delete(int mindId) {
        boolean success = true;
        List<MindMap> mapList = this.list();
        if (mapList.removeIf(item -> item.getId().equals(mindId))) {
            String fileName = this.dataFile();
            success = DataKit.writeJsonFile(fileName, mapList.toString());
            LogKit.info(String.format("删除思维导图数据：%s", mindId));
        }
        return success;
    }
    
    public MindMap detail(int mindId) {
        List<MindMap> mapList = this.list();
        List<MindMap> search = mapList.stream()
                .filter(item -> item.getId().equals(mindId))
                .collect(Collectors.toList());
        
        if (!search.isEmpty()) {
            return search.get(0);
        }
        return new MindMap();
    }
    
    public List<MindMap> list() {
        String fileName = this.dataFile();
        String mindStr = DataKit.readJsonFile(fileName);
        List<MindMap> mapList = JSONArray.parseArray(mindStr, MindMap.class);
        if (null == mapList) {
            return new ArrayList<>();
        } else {
            return mapList;
        }
    }
    
    public List<MindMap> documentList() {
        List<MindMap> mapList = this.list();
        List<MindMap> result = mapList.stream()
                .filter(item -> item.getType().equals(1))
                .collect(Collectors.toList());
        if (!result.isEmpty()) {
            result.sort(Comparator.comparing(MindMap::getId));
        }
        return result;
    }
    
    public List<MindMap> categoryList() {
        List<MindMap> mapList = this.list();
        List<MindMap> result = mapList.stream()
                .filter(item -> item.getType().equals(0))
                .collect(Collectors.toList());
        if (!result.isEmpty()) {
            result.sort(Comparator.comparing(MindMap::getId));
        }
        return result;
    }
    
    public Kv chartList() {
        List<MindMap> mapList = this.list();
        List<MindMap> result = mapList.stream()
                .filter(item -> item.getParentId().equals(0))
                .collect(Collectors.toList());

        Kv meta = Kv.by("name", "mindMap")
                .set("author", "Sunron")
                .set("version", "1.0.0");
        Kv charts = Kv.by("meta", meta);
        if (!result.isEmpty()) {
            MindMap map = result.get(0);
            List<MindMap> child = getChildren(map.getId(), mapList);
            if (null != child && !child.isEmpty()) {
                map.setChildren(child);
            }
            charts.set("data", map);
        }
        return charts;
    }

    //public List<MindMap> chartList() {
    //    List<MindMap> mapList = this.list();
    //    List<MindMap> result = mapList.stream()
    //            .filter(item -> item.getParentId().equals(0))
    //            .collect(Collectors.toList());
    //    
    //    List<MindMap> charts = new ArrayList<>();
    //    if (!result.isEmpty()) {
    //        for (MindMap map : result) {
    //            List<MindMap> child = getChildren(map.getValue(), mapList);
    //            if (null != child && !child.isEmpty()) {
    //                map.setChildren(child);
    //            }
    //            charts.add(map);
    //        }
    //    }
    //    return charts;
    //}

    private List<MindMap> getChildren(Integer parentId, List<MindMap> mapList) {
        List<MindMap> result = mapList.stream()
                .filter(item -> item.getParentId().equals(parentId))
                .collect(Collectors.toList());
        if (!result.isEmpty()) {
            List<MindMap> charts = new ArrayList<>();
            for (MindMap map : result) {
                List<MindMap> child = this.getChildren(map.getId(), mapList);
                if (null != child && !child.isEmpty()) {
                    map.setChildren(child);
                }
                charts.add(map);
            }
            return charts;
        }
        return null;
    }
    
    public List<MindMap> parentList() {
        List<MindMap> mapList = this.list();
        List<MindMap> result = mapList.stream()
                .filter(item -> item.getType().equals(0))
                .collect(Collectors.toList());
        if (!result.isEmpty()) {
            result.sort(Comparator.comparing(MindMap::getParentId));
        } else {
            MindMap map = new MindMap();
            map.setId(0);
            map.setTopic("根目录");
            result = new ArrayList<>();
            result.add(map);
        }
        return result;
    }
    
    public MindMap searchMindMap(String keyword) {
        List<MindMap> mapList = this.list();
        List<MindMap> search = mapList.stream()
                .filter(item -> item.getTopic().contains(keyword) && item.getType().equals(1))
                .collect(Collectors.toList());

        if (!search.isEmpty()) {
            return search.get(0);
        }
        return new MindMap();
    }
}
